home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / template_compiler.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  30.3 KB  |  930 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. from util import checkU
  5.  
  6. def genRepeatText(varname, tid, prefix, text):
  7.     checkU(text)
  8.     return u'%s%s.write(%s)\n' % (prefix, varname, repr(text))
  9.  
  10.  
  11. def genRepeatTranslate(varname, tid, prefix, args):
  12.     (text, funcDict) = args
  13.     checkU(text)
  14.     text = u' '.join(str(text).strip().split())
  15.     if len(funcDict) == 0:
  16.         return u'%s%s.write(_(%s))\n' % (prefix, varname, repr(text))
  17.     else:
  18.         dictName = generateId()
  19.         out = u'%s%s = {}\n' % (prefix, dictName)
  20.         for name in funcDict:
  21.             temp = generateId()
  22.             out = u'%s%s%s = StringIO()\n' % (out, prefix, temp)
  23.             for func, fargs in funcDict[name]:
  24.                 val = func(temp, tid, prefix, fargs)
  25.                 checkU(val)
  26.                 out = u'%s%s' % (out, val)
  27.             
  28.             out = u'%s%s%s.seek(0)\n' % (out, prefix, temp)
  29.             out = u'%s%s%s[%s] = %s.read()\n' % (out, prefix, dictName, repr(str(name)), temp)
  30.         
  31.         out = u'%s%s%s.write(Template(_(%s)).substitute(%s))\n' % (out, prefix, varname, repr(text), dictName)
  32.         return out
  33.  
  34.  
  35. def genRepeatTextHide(varname, tid, prefix, args):
  36.     (ifValue, text) = args
  37.     checkU(text)
  38.     out = u'%sif not (%s):\n' % (prefix, ifValue)
  39.     out = u'%s%s    %s.write(%s)\n' % (out, prefix, varname, repr(text))
  40.     return out
  41.  
  42.  
  43. def genQuoteAttr(varname, tid, prefix, value):
  44.     return u'%s%s.write(quoteattr(urlencode(%s)))\n' % (prefix, varname, value)
  45.  
  46.  
  47. def genRawAttr(varname, tid, prefix, value):
  48.     return u'%s%s.write(quoteattr(%s))\n' % (prefix, varname, value)
  49.  
  50.  
  51. def genRepeatTID(varname, tid, prefix, args):
  52.     return u'%s%s.write(quoteattr(tid))\n' % (prefix, varname)
  53.  
  54.  
  55. def genRepeatEvalEscape(varname, tid, prefix, replace):
  56.     return u'%s%s.write(escape(%s))\n' % (prefix, varname, replace)
  57.  
  58.  
  59. def genRepeatEval(varname, tid, prefix, replace):
  60.     return u'%s%s.write(%s)\n' % (prefix, varname, replace)
  61.  
  62.  
  63. def genRepeatIncludeHide(varname, tid, prefix, args):
  64.     (ifValue, name) = args
  65.     f = open(resource.path('templates/%s' % name), 'r')
  66.     text = f.read()
  67.     f.close()
  68.     out = u'%sif not (%s):\n' % (prefix, ifValue)
  69.     out = u'%s%s    %s.write(%s)\n' % (out, prefix, varname, repr(text.decode('utf-8')))
  70.     return out
  71.  
  72.  
  73. def genHideSection(varname, tid, prefix, args):
  74.     (ifValue, funcList) = args
  75.     out = u'%sif not (%s):\n' % (prefix, ifValue)
  76.     for func, newargs in funcList:
  77.         val = func(varname, tid, prefix + '    ', newargs)
  78.         checkU(val)
  79.         out = u'%s%s' % (out, val)
  80.     
  81.     return out
  82.  
  83.  
  84. def genQuoteAndFillAttr(varname, tid, prefix, value):
  85.     checkU(value)
  86.     return u'%s%s.write(quoteAndFillAttr(%s,locals()))\n' % (prefix, varname, repr(value))
  87.  
  88.  
  89. def genUpdateHideOnView(varname, tid, prefix, args):
  90.     (viewName, ifValue, attrs, nodeId) = args
  91.     out = u'%s_hideFunc = lambda : %s\n' % (prefix, ifValue)
  92.     out = u'%s%s_dynHide = _hideFunc()\n' % (out, prefix)
  93.     out = u'%s%sif _dynHide:\n' % (out, prefix)
  94.     out = u'%s%s    %s.write(u" style=\\"display:none\\">")\n' % (out, prefix, varname)
  95.     out = u'%s%selse:\n%s    %s.write(u">")\n' % (out, prefix, prefix, varname)
  96.     out = u'%s%shandle.addUpdateHideOnView(%s,%s,_hideFunc,_dynHide)\n' % (out, prefix, repr(nodeId), viewName)
  97.     return out
  98.  
  99.  
  100. def genInsertBodyTagExtra(varname, tid, prefix, args):
  101.     return u'%s%s.write(u" " + bodyTagExtra)\n' % (prefix, varname)
  102.  
  103.  
  104. def genExecuteTemplate(varname, tid, prefix, args):
  105.     (filename, methodArgs) = args
  106.     methodCall = u'fillStaticTemplate(%r, onlyBody=True' % filename
  107.     for name, value in methodArgs.items():
  108.         methodCall += u', %s=%s' % (name, value)
  109.     
  110.     methodCall += u')'
  111.     return u'%s%s.write(%s)\n' % (prefix, varname, methodCall)
  112.  
  113. from xml import sax
  114. from StringIO import StringIO
  115. from templatehelper import quoteattr, escape, HTMLPattern, attrPattern, resourcePattern, rawAttrPattern, generateId
  116. import re
  117. import os
  118. import stat
  119.  
  120. class res:
  121.     
  122.     def path(self, rel_path):
  123.         return os.path.join(resourcePath, rel_path)
  124.  
  125.  
  126. resource = res()
  127.  
  128. def setResourcePath(path):
  129.     global resourcePath
  130.     resourcePath = path
  131.  
  132.  
  133. def compileTemplate(inFile, *args, **kwargs):
  134.     handle = MetaHandle()
  135.     tcc = TemplateContentCompiler(handle, inFile, *args, **kwargs)
  136.     p = sax.make_parser()
  137.     p.setFeature(sax.handler.feature_external_ges, False)
  138.     p.setContentHandler(tcc)
  139.     p.parse(resource.path('templates/%s' % inFile))
  140.     return (tcc, handle)
  141.  
  142.  
  143. def findTemplates(tpath):
  144.     templates = []
  145.     folders = []
  146.     for template in os.listdir(tpath):
  147.         if template.find('.svn') == -1 and template.find('_svn') == -1:
  148.             if not template.startswith('.') and template.startswith('#') and template.endswith('~') and template.endswith('.js'):
  149.                 pass
  150.             if not template.endswith('.html'):
  151.                 mode = os.stat(os.path.join(tpath, template))[stat.ST_MODE]
  152.                 if stat.S_ISDIR(mode):
  153.                     folders.append(template)
  154.                 else:
  155.                     templates.append(template)
  156.         stat.S_ISDIR(mode)
  157.     
  158.     return (folders, templates)
  159.  
  160.  
  161. def modifiedTime(dir):
  162.     maxTime = 0
  163.     
  164.     try:
  165.         for dirpath, dirnames, filenames in os.walk(dir):
  166.             for f in filenames:
  167.                 if -1 == dirpath.find('.svn') and -1 == dirpath.find('_svn'):
  168.                     t = os.stat(os.path.join(dirpath, f)).st_mtime
  169.                     if t > maxTime:
  170.                         maxTime = t
  171.                     
  172.                 t > maxTime
  173.             
  174.         
  175.         return maxTime
  176.     except:
  177.         return 0
  178.  
  179.  
  180.  
  181. def compileAllTemplates(root):
  182.     setResourcePath(os.path.join(root, 'resources'))
  183.     source = resource.path('templates')
  184.     sourceTime = modifiedTime(source)
  185.     dest = resource.path(os.path.join('..', 'portable', 'compiled_templates'))
  186.     if not os.path.isdir(dest):
  187.         os.makedirs(dest)
  188.     
  189.     destTime = modifiedTime(dest)
  190.     compilerTime = os.stat(resource.path(os.path.join('..', 'portable', 'template_compiler.py'))).st_mtime
  191.     if sourceTime > destTime or compilerTime > destTime:
  192.         compileTemplates()
  193.     
  194.  
  195.  
  196. def compileTemplates(tpath = None):
  197.     outdir = resource.path(os.path.join('..', 'portable', 'compiled_templates'))
  198.     if not os.path.isdir(outdir):
  199.         os.makedirs(outdir)
  200.     
  201.     indir = resource.path('templates')
  202.     if tpath is not None:
  203.         print 'Compiling %s' % tpath
  204.         outdir = os.path.join(outdir, tpath)
  205.         
  206.         try:
  207.             os.makedirs(outdir)
  208.         except:
  209.             pass
  210.  
  211.         indir = os.path.join(indir, tpath)
  212.     
  213.     manifest = open(os.path.join(outdir, '__init__.py'), 'wb')
  214.     manifest.write('# This is a generated file. Do not edit.\n\n')
  215.     (folders, templates) = findTemplates(indir)
  216.     for template in templates:
  217.         outFile = os.path.join(outdir, template.replace('-', '_') + '.py')
  218.         if tpath is None:
  219.             sourceFile = template
  220.         else:
  221.             sourceFile = os.path.join(tpath, template)
  222.         print "Compiling '%s' template to %s" % (sourceFile, outFile)
  223.         (tcc, handle) = compileTemplate(sourceFile)
  224.         f = open(outFile, 'wb')
  225.         f.write(tcc.getOutput().encode('utf-8'))
  226.         f.close()
  227.         manifest.write('import %s\n' % template.replace('/', '.').replace('\\', '.').replace('-', '_'))
  228.     
  229.     for folder in folders:
  230.         manifest.write('import %s\n' % folder.replace('/', '.').replace('\\', '.').replace('-', '_'))
  231.         compileTemplates(folder)
  232.     
  233.     manifest.close()
  234.  
  235.  
  236. class TemplateError(Exception):
  237.     
  238.     def __init__(self, message):
  239.         self.message = message
  240.  
  241.     
  242.     def __str__(self):
  243.         return self.message
  244.  
  245.  
  246.  
  247. class TemplateContentCompiler(sax.handler.ContentHandler):
  248.     
  249.     def __init__(self, handle, name, debug = False, onlyBody = False, addIdToTopLevelElement = False):
  250.         self.handle = handle
  251.         self.debug = debug
  252.         self.onlyBody = onlyBody
  253.         self.addIdToTopLevelElement = addIdToTopLevelElement
  254.         self.name = name
  255.         self.isDynamic = False
  256.  
  257.     
  258.     def getOperationList(self):
  259.         return self.outputLists[0]
  260.  
  261.     
  262.     def getOutput(self, data = None):
  263.         fo = StringIO()
  264.         self.render(fo)
  265.         return fo.getvalue()
  266.  
  267.     
  268.     def render(self, fileobj):
  269.         fileobj.write(u'# This is a generated file. Do not edit.\n')
  270.         fileobj.write(u'from template import Handle, fillAttr, quoteAndFillAttr, fillStaticTemplate\n')
  271.         fileobj.write(u'from StringIO import StringIO\n')
  272.         fileobj.write(u'from xhtmltools import urlencode\n')
  273.         fileobj.write(u'from templatehelper import quoteattr, escape\n')
  274.         fileobj.write(u'from string import Template\n')
  275.         fileobj.write(u'import app\n')
  276.         fileobj.write(u'import views\n')
  277.         fileobj.write(u'import sorts\n')
  278.         fileobj.write(u'import indexes\n')
  279.         fileobj.write(u'import filters\n')
  280.         fileobj.write(u'import resources\n')
  281.         fileobj.write(u'import gtcache\n')
  282.         fileobj.write(u'_ = gtcache.gettext\n')
  283.         fileobj.write(u'def fillTemplate(domHandler, dtvPlatform, eventCookie, bodyTagExtra, *args, **kargs):\n')
  284.         self.handle.render(fileobj)
  285.         fileobj.write(u'\n\n    out = StringIO()\n')
  286.         if not self.onlyBody:
  287.             fileobj.write(u'    out.write(u"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>\\n<!DOCTYPE html PUBLIC \\"-//W3C//DTD XHTML 1.0 Strict//EN\\" \\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\\">\\n")\n')
  288.         
  289.         for count in range(len(self.outputLists[0])):
  290.             (func, args) = self.outputLists[0][count]
  291.             fileobj.write(func(u'out', u'', u'    ', args))
  292.         
  293.         fileobj.write(u'    out.seek(0)\n')
  294.         fileobj.write(u'\n\n    return (out, handle)\n')
  295.  
  296.     
  297.     def returnIf(self, bool, value):
  298.         if bool:
  299.             return value
  300.         else:
  301.             return ''
  302.  
  303.     
  304.     def startDocument(self):
  305.         print 'Starting compile of %s' % self.name
  306.         self.elementStack = []
  307.         self.inInclude = False
  308.         self.inRepeatView = False
  309.         self.inRepeatWithTemplate = False
  310.         self.inUpdateView = False
  311.         self.inConfigUpdate = False
  312.         self.inReplace = False
  313.         self.inStaticReplace = False
  314.         self.inExecOnUnload = False
  315.         self.inExecOnLoad = False
  316.         self.repeatDepth = 0
  317.         self.hotspotDepth = -1
  318.         self.hotspotTagName = ''
  319.         self.replaceDepth = 0
  320.         self.hiding = False
  321.         self.hideDepth = []
  322.         self.depth = 0
  323.         self.bodyDepth = None
  324.         self.repeatName = ''
  325.         self.started = not (self.onlyBody)
  326.         self.outputLists = [
  327.             []]
  328.         self.outputText = []
  329.         self.hidingParams = []
  330.         self.translateDepth = []
  331.         self.translateText = []
  332.         self.translateDict = []
  333.         self.translateName = []
  334.         self.inRaw = False
  335.         self.rawDepth = None
  336.  
  337.     
  338.     def endDocument(self):
  339.         print 'Ending compile'
  340.         self.endText()
  341.  
  342.     
  343.     def startElement(self, name, attrs):
  344.         self.depth = self.depth + 1
  345.         if name == 'body':
  346.             self.bodyDepth = self.depth
  347.         
  348.         if len(self.translateDepth) > 0 and self.depth == self.translateDepth[-1] + 1:
  349.             if not attrs.has_key('i18n:name'):
  350.                 print 'in raw for %s' % name
  351.                 self.inRaw = True
  352.                 self.rawDepth = self.depth
  353.             else:
  354.                 self.translateName[-1] = attrs['i18n:name']
  355.                 self.translateText[-1] += u'${%s}' % self.translateName[-1]
  356.                 self.endText()
  357.                 self.outputLists.append([])
  358.         
  359.         if self.inRaw:
  360.             self.translateText[-1] += u'<%s' % name
  361.             for attr in attrs.keys():
  362.                 self.translateText[-1] += u' %s="%s"' % (attr, quoteattr(attrs[attr]))
  363.             
  364.             self.translateText[-1] += u'>'
  365.         elif self.onlyBody and not (self.started):
  366.             if name == 'body':
  367.                 self.started = True
  368.             
  369.         elif not self.started:
  370.             pass
  371.         elif 't:repeatForView' in attrs.keys():
  372.             if 't:containerDiv' in attrs.keys():
  373.                 self.inRepeatWithContainerDiv = True
  374.                 self.repeatContainerId = generateId()
  375.                 self.addElementStart('div', {
  376.                     'id': self.repeatContainerId })
  377.             else:
  378.                 self.inRepeatWithContainerDiv = False
  379.             self.startRepeat(attrs['t:repeatForView'])
  380.             if 't:repeatTemplate' not in attrs.keys():
  381.                 self.addElementStart(name, attrs, addId = True)
  382.                 self.inRepeatWithTemplate = False
  383.             else:
  384.                 name = attrs['t:repeatTemplate']
  385.                 self.addFillTemplate(name, addIdToTopLevelElement = True)
  386.                 self.outputLists.append([])
  387.                 self.inRepeatWithTemplate = True
  388.         elif 't:updateForView' in attrs.keys():
  389.             self.startUpdate(attrs['t:updateForView'])
  390.             self.addElementStart(name, attrs, addId = True)
  391.         elif 't:updateForConfigChange' in attrs.keys():
  392.             self.startConfigUpdate()
  393.             self.addElementStart(name, attrs, addId = True)
  394.         elif 't:hideIf' in attrs.keys():
  395.             ifValue = attrs['t:hideIf']
  396.             if attrs.has_key('t:updateHideOnView'):
  397.                 if self.inRepeatView or self.inUpdateView:
  398.                     print 'Warning: t:updateHideOnView is unsupported inside a repeat view'
  399.                 
  400.                 self.addUpdateHideOnView(attrs['t:updateHideOnView'], name, ifValue, attrs)
  401.             else:
  402.                 self.startHiding(ifValue)
  403.                 self.addElementStart(name, attrs)
  404.         elif 't:showIf' in attrs.keys():
  405.             ifValue = u'not (%s)' % attrs['t:showIf']
  406.             if attrs.has_key('t:updateHideOnView'):
  407.                 if self.inRepeatView or self.inUpdateView:
  408.                     print 'Warning: t:updateHideOnView is unsupported inside a repeat view'
  409.                 
  410.                 self.addUpdateHideOnView(attrs['t:updateHideOnView'], name, ifValue, attrs)
  411.             else:
  412.                 self.startHiding(ifValue)
  413.                 self.addElementStart(name, attrs)
  414.         elif 'i18n:translate' in attrs.keys():
  415.             self.addElementStart(name, attrs)
  416.             self.translateDepth.append(self.depth)
  417.             self.translateText.append('')
  418.             self.translateDict.append({ })
  419.             self.translateName.append('')
  420.         elif name == 't:include':
  421.             self.addInclude(attrs['filename'])
  422.         elif 't:replace' in attrs.keys():
  423.             self.addElementStart(name, attrs)
  424.             replace = attrs['t:replace']
  425.             self.addEvalEscape(replace)
  426.             self.inReplace = True
  427.             self.replaceDepth = self.depth
  428.         elif 't:replaceMarkup' in attrs.keys():
  429.             self.addElementStart(name, attrs)
  430.             replace = attrs['t:replaceMarkup']
  431.             self.addEval(replace)
  432.             self.inReplace = True
  433.             self.replaceDepth = self.depth
  434.         elif name == 't:execOnUnload':
  435.             self.inExecOnUnload = True
  436.             self.code = ''
  437.         elif name == 't:execOnLoad':
  438.             self.inExecOnLoad = True
  439.             self.code = ''
  440.         elif name == 't:include':
  441.             f = open(resource.path('templates/%s' % attrs['filename']), 'r')
  442.             html = f.read()
  443.             f.close()
  444.             self.addText(html.decode('utf-8'))
  445.         elif name == 't:staticReplaceMarkup':
  446.             replace = attrs['t:replaceData']
  447.             self.addEval(replace)
  448.             self.inStaticReplace = True
  449.         elif name == 't:staticReplace':
  450.             replace = attrs['t:replaceData']
  451.             self.addEvalEscape(replace)
  452.             self.inStaticReplace = True
  453.         elif name == 't:includeTemplate':
  454.             self.addFillTemplate(attrs['filename'])
  455.         elif name == 't:executeTemplate':
  456.             args = dict(attrs.items())
  457.             filename = args.pop('filename')
  458.             self.addInstruction(genExecuteTemplate, (filename, args))
  459.         elif name == 't:triggerActionOnLoad':
  460.             self.handle.addTriggerActionURLOnLoad(attrs['url'])
  461.         elif name == 't:triggerActionOnUnload':
  462.             self.handle.addTriggerActionURLOnUnload(attrs['url'])
  463.         elif 't:hotspot' in attrs.keys():
  464.             self.addHotspot(name, attrs['t:hotspot'])
  465.         else:
  466.             self.addElementStart(name, attrs)
  467.  
  468.     
  469.     def endElement(self, name):
  470.         if not self.started:
  471.             pass
  472.         elif self.inRaw:
  473.             self.translateText[-1] += u'</%s>' % name
  474.         elif self.onlyBody and name == 'body':
  475.             self.started = False
  476.         elif name == 't:include':
  477.             pass
  478.         elif name == 't:staticReplace':
  479.             self.inStaticReplace = False
  480.         elif name == 't:staticReplaceMarkup':
  481.             self.inStaticReplace = False
  482.         elif name == 't:filter':
  483.             pass
  484.         elif name == 't:sort':
  485.             pass
  486.         elif name == 't:includeTemplate':
  487.             pass
  488.         elif name == 't:executeTemplate':
  489.             pass
  490.         elif name == 't:triggerActionOnUnload':
  491.             pass
  492.         elif name == 't:triggerActionOnLoad':
  493.             pass
  494.         elif self.hiding and self.depth == self.hideDepth[-1]:
  495.             self.addText(u'</%s>' % name)
  496.             self.endHiding()
  497.         elif self.inReplace and self.depth == self.replaceDepth:
  498.             self.addText(u'</%s>' % name)
  499.             self.inReplace = False
  500.         elif self.inRepeatView and self.depth == self.repeatDepth:
  501.             if self.inRepeatWithTemplate:
  502.                 self.endText()
  503.                 nestedOutputs = self.outputLists.pop()
  504.                 if nestedOutputs:
  505.                     m = "Elements with t:repeatTemplate, can't have children"
  506.                     raise ValueError(m)
  507.                 
  508.             else:
  509.                 self.addText(u'</%s>' % name)
  510.                 self.endText()
  511.             repeatList = self.endRepeat()
  512.             if self.inRepeatWithContainerDiv:
  513.                 self.endElement('div')
  514.                 self.handle.addView(self.repeatContainerId, 'containerDiv', repeatList, self.repeatName)
  515.             else:
  516.                 repeatId = generateId()
  517.                 self.addText(u'<span id="%s"/>' % quoteattr(repeatId))
  518.                 self.handle.addView(repeatId, 'nextSibling', repeatList, self.repeatName)
  519.         elif self.inUpdateView and self.depth == self.repeatDepth:
  520.             self.addText(u'</%s>' % name)
  521.             self.endText()
  522.             repeatList = self.endUpdate()
  523.             repeatId = generateId()
  524.             self.addText(u'<span id="%s"/>' % quoteattr(repeatId))
  525.             self.handle.addUpdate(repeatId, 'nextSibling', repeatList, self.repeatName)
  526.         elif self.inConfigUpdate and self.depth == self.repeatDepth:
  527.             self.addText(u'</%s>' % name)
  528.             self.endText()
  529.             repeatList = self.endConfigUpdate()
  530.             repeatId = generateId()
  531.             self.addText(u'<span id="%s"/>' % quoteattr(repeatId))
  532.             self.handle.addConfigUpdate(repeatId, 'nextSibling', repeatList)
  533.         elif len(self.translateDepth) > 0 and self.depth == self.translateDepth[-1]:
  534.             self.addTranslation()
  535.             self.addText(u'</%s>' % name)
  536.         elif self.depth == self.hotspotDepth:
  537.             self.addText(u'</%s><!-- HOT SPOT END -->' % self.hotspotTagName)
  538.             self.hotspotDepth = -1
  539.         elif name == 't:execOnUnload':
  540.             self.inExecOnUnload = False
  541.             self.handle.addExecOnUnload(self.code)
  542.         elif name == 't:execOnLoad':
  543.             self.inExecOnLoad = False
  544.             self.handle.addExecOnLoad(self.code)
  545.         else:
  546.             self.addText(u'</%s>' % name)
  547.         if len(self.translateDepth) > 0 and self.depth == self.translateDepth[-1] + 1:
  548.             if self.inRaw:
  549.                 print 'ending raw for %s' % name
  550.                 self.inRaw = False
  551.             else:
  552.                 self.endText()
  553.                 self.translateDict[-1][self.translateName[-1]] = self.outputLists.pop()
  554.         
  555.         self.depth = self.depth - 1
  556.  
  557.     
  558.     def characters(self, data):
  559.         if not self.started:
  560.             pass
  561.         elif self.inReplace or self.inStaticReplace:
  562.             pass
  563.         elif len(self.translateDepth) > 0 or self.depth == self.translateDepth[-1] or self.inRaw:
  564.             self.translateText[-1] += data
  565.         elif self.inExecOnUnload or self.inExecOnLoad:
  566.             self.code += data
  567.         else:
  568.             self.addTextEscape(data)
  569.  
  570.     
  571.     def skippedEntity(self, name):
  572.         self.addText(u'&%s;' % name)
  573.  
  574.     
  575.     def addTranslation(self):
  576.         self.translateDepth.pop()
  577.         self.translateName.pop()
  578.         self.addInstruction(genRepeatTranslate, (self.translateText.pop(), self.translateDict.pop()))
  579.  
  580.     
  581.     def addInclude(self, template):
  582.         f = open(resource.path('templates/%s' % template), 'r')
  583.         html = f.read()
  584.         f.close()
  585.         self.addText(html)
  586.  
  587.     
  588.     def addFillTemplate(self, name, *args, **kwargs):
  589.         print "  compiling '%s' subtemplate" % name
  590.         (tcc, handle) = compileTemplate(name, onlyBody = True, *args, **kwargs)
  591.         if tcc.isDynamic:
  592.             self.isDynamic = True
  593.             if self.inUpdateView and self.inConfigUpdate or self.inRepeatView:
  594.                 raise TemplateError, 'Nested Dynamic tags'
  595.             
  596.         
  597.         self.handle.addSubHandle(handle)
  598.         self.addInstructions(tcc.getOperationList())
  599.  
  600.     
  601.     def addIdAndClose(self):
  602.         self.addText(' id="')
  603.         self.addInstruction(genRepeatTID, None)
  604.         self.addText('">')
  605.  
  606.     
  607.     def startRepeat(self, name):
  608.         if self.inUpdateView and self.inConfigUpdate or self.inRepeatView:
  609.             raise TemplateError, 'Nested Dynamic tags'
  610.         
  611.         self.endText()
  612.         self.inRepeatView = True
  613.         self.isDynamic = True
  614.         self.repeatDepth = self.depth
  615.         self.repeatName = name
  616.         self.outputLists.append([])
  617.  
  618.     
  619.     def startUpdate(self, name):
  620.         if self.inUpdateView and self.inConfigUpdate or self.inRepeatView:
  621.             raise TemplateError, 'Nested Dynamic tags'
  622.         
  623.         self.endText()
  624.         self.inUpdateView = True
  625.         self.isDynamic = True
  626.         self.repeatDepth = self.depth
  627.         self.repeatName = name
  628.         self.outputLists.append([])
  629.  
  630.     
  631.     def startConfigUpdate(self):
  632.         if self.inUpdateView and self.inConfigUpdate or self.inRepeatView:
  633.             raise TemplateError, 'Nested Dynamic tags'
  634.         
  635.         self.endText()
  636.         self.inConfigUpdate = True
  637.         self.isDynamic = True
  638.         self.repeatDepth = self.depth
  639.         self.outputLists.append([])
  640.  
  641.     
  642.     def endRepeat(self):
  643.         self.inRepeatView = False
  644.         return self.outputLists.pop()
  645.  
  646.     
  647.     def endUpdate(self):
  648.         self.inUpdateView = False
  649.         return self.outputLists.pop()
  650.  
  651.     
  652.     def endConfigUpdate(self):
  653.         self.inConfigUpdate = False
  654.         return self.outputLists.pop()
  655.  
  656.     
  657.     def startHiding(self, ifValue):
  658.         self.endText()
  659.         self.hidingParams.append(ifValue)
  660.         self.outputLists.append([])
  661.         self.hideDepth.append(self.depth)
  662.         self.hiding = True
  663.  
  664.     
  665.     def endHiding(self):
  666.         self.endText()
  667.         ifValue = self.hidingParams.pop()
  668.         funcList = self.outputLists.pop()
  669.         self.hideDepth.pop()
  670.         self.hiding = len(self.hideDepth) > 0
  671.         self.addInstruction(genHideSection, (ifValue, funcList))
  672.  
  673.     
  674.     def addText(self, text):
  675.         self.outputText.append(text)
  676.  
  677.     
  678.     def addElementStart(self, name, attrs, addId = False):
  679.         if self.bodyDepth is not None and self.depth == self.bodyDepth + 1 and self.addIdToTopLevelElement:
  680.             addId = True
  681.         
  682.         self.addText(u'<%s' % name)
  683.         for key in attrs.keys():
  684.             if not key.startswith('t:'):
  685.                 pass
  686.             if not key.startswith('i18n:') or key == 't:contextMenu':
  687.                 self.addAttr(key, attrs[key])
  688.                 continue
  689.         
  690.         if name.lower() == 'body':
  691.             self.addInstruction(genInsertBodyTagExtra, None)
  692.         
  693.         if addId:
  694.             self.addIdAndClose()
  695.         else:
  696.             self.addText(u'>')
  697.  
  698.     
  699.     def addTextEscape(self, text):
  700.         self.outputText.append(escape(text))
  701.  
  702.     
  703.     def addUpdateHideOnView(self, viewName, name, ifValue, attrs):
  704.         nodeId = generateId()
  705.         self.addText(u'<%s' % name)
  706.         for key in attrs.keys():
  707.             if key not in ('t:hideIf', 't:updateHideOnView', 'style'):
  708.                 self.addText(u' %s=' % key)
  709.                 self.addInstruction(genQuoteAndFillAttr, attrs[key])
  710.                 continue
  711.         
  712.         self.addText(u' id="%s"' % quoteattr(nodeId))
  713.         self.addInstruction(genUpdateHideOnView, (viewName, ifValue, attrs, nodeId))
  714.  
  715.     
  716.     def addAttr(self, attr, value):
  717.         self.addText(u' %s="' % attr)
  718.         self.addDynamicText(value)
  719.         self.addText('"')
  720.  
  721.     
  722.     def addDynamicText(self, value):
  723.         match = attrPattern.match(value)
  724.         if match:
  725.             while match:
  726.                 self.addText(quoteattr(match.group(1)))
  727.                 self.addInstruction(genQuoteAttr, match.group(2))
  728.                 value = match.group(3)
  729.                 match = attrPattern.match(value)
  730.             self.addText(u'%s' % quoteattr(value))
  731.         else:
  732.             match = rawAttrPattern.match(value)
  733.             if match:
  734.                 while match:
  735.                     self.addText(quoteattr(match.group(1)))
  736.                     self.addInstruction(genRawAttr, match.group(2))
  737.                     value = match.group(3)
  738.                     match = rawAttrPattern.match(value)
  739.                 self.addText(u'%s' % quoteattr(value))
  740.             else:
  741.                 match = resourcePattern.match(value)
  742.                 if match:
  743.                     self.addInstruction(genRawAttr, u'resources.url(%s)' % repr(match.group(1)))
  744.                 else:
  745.                     self.addText(quoteattr(value))
  746.  
  747.     
  748.     def addHotspot(self, name, id):
  749.         self.hotspotDepth = self.depth
  750.         self.hotspotTagName = name
  751.         self.addText(u'<!-- HOT SPOT ')
  752.         self.addDynamicText(id)
  753.         self.addText(u' -->')
  754.         self.addElementStart(name, {
  755.             'id': id })
  756.  
  757.     
  758.     def addEval(self, replace):
  759.         self.addInstruction(genRepeatEval, replace)
  760.  
  761.     
  762.     def addEvalEscape(self, replace):
  763.         self.addInstruction(genRepeatEvalEscape, replace)
  764.  
  765.     
  766.     def endText(self):
  767.         if len(self.outputText) > 0:
  768.             self.addInstruction(genRepeatText, u''.join(self.outputText))
  769.         
  770.         self.outputText = []
  771.  
  772.     
  773.     def addInstruction(self, instruction, args):
  774.         if instruction != genRepeatText:
  775.             self.endText()
  776.         
  777.         self.outputLists[-1].append((instruction, args))
  778.  
  779.     
  780.     def addInstructions(self, instructions):
  781.         self.endText()
  782.         for ins, arg in instructions:
  783.             self.addInstruction(ins, arg)
  784.         
  785.  
  786.  
  787.  
  788. class MetaHandle:
  789.     
  790.     def __init__(self):
  791.         self.trackedViews = []
  792.         self.updateRegions = []
  793.         self.configUpdateRegions = []
  794.         self.subHandles = []
  795.         self.triggerActionURLsOnLoad = []
  796.         self.triggerActionURLsOnUnload = []
  797.         self.execOnUnload = None
  798.         self.execOnLoad = None
  799.  
  800.     
  801.     def addTriggerActionURLOnLoad(self, url):
  802.         self.triggerActionURLsOnLoad.append(str(url))
  803.  
  804.     
  805.     def addTriggerActionURLOnUnload(self, url):
  806.         self.triggerActionURLsOnUnload.append(str(url))
  807.  
  808.     
  809.     def getTriggerActionURLsOnLoad(self):
  810.         return self.triggerActionURLsOnLoad
  811.  
  812.     
  813.     def getTriggerActionURLsOnUnload(self):
  814.         return self.triggerActionURLsOnUnload
  815.  
  816.     
  817.     def addExecOnUnload(self, code):
  818.         self.execOnUnload = code
  819.  
  820.     
  821.     def addExecOnLoad(self, code):
  822.         self.execOnLoad = code
  823.  
  824.     
  825.     def addView(self, anchorId, anchorType, templateFuncs, name):
  826.         tv = (anchorId, anchorType, templateFuncs, name)
  827.         self.trackedViews.append(tv)
  828.  
  829.     
  830.     def addUpdate(self, anchorId, anchorType, templateFuncs, name):
  831.         ur = (anchorId, anchorType, templateFuncs, name)
  832.         self.updateRegions.append(ur)
  833.  
  834.     
  835.     def addConfigUpdate(self, anchorId, anchorType, templateFuncs):
  836.         ur = (anchorId, anchorType, templateFuncs)
  837.         self.configUpdateRegions.append(ur)
  838.  
  839.     
  840.     def addSubHandle(self, handle):
  841.         self.subHandles.append(handle)
  842.  
  843.     
  844.     def render(self, fileobj, varname = 'handle'):
  845.         prefix = u'    '
  846.         ending = u'\n'
  847.         fileobj.write(u'%s# Start of handle%s%s' % (prefix, ending, ending))
  848.         fileobj.write(u'%s# Start user code%s' % (prefix, ending))
  849.         if self.execOnLoad is not None:
  850.             for line in self.execOnLoad.splitlines():
  851.                 fileobj.write(u'%s%s%s' % (prefix, line, ending))
  852.             
  853.         
  854.         if self.execOnUnload is not None:
  855.             fileobj.write(u'%s%sdef _execOnUnload():%s' % (ending, prefix, ending))
  856.             for line in self.execOnUnload.splitlines():
  857.                 fileobj.write(u'%s    %s%s' % (prefix, line, ending))
  858.             
  859.         
  860.         fileobj.write(u'%s# End user code%s%s' % (prefix, ending, ending))
  861.         fileobj.write(u'%slocalvars = locals()%s' % (prefix, ending))
  862.         fileobj.write(u'%slocalvars.update(globals())%s' % (prefix, ending))
  863.         if self.execOnUnload is not None:
  864.             fileobj.write(u'%s%s = Handle(domHandler, localvars, onUnlink = _execOnUnload)%s%s' % (prefix, varname, ending, ending))
  865.         else:
  866.             fileobj.write(u'%s%s = Handle(domHandler, localvars, onUnlink = lambda:None)%s%s' % (prefix, varname, ending, ending))
  867.         count = 0
  868.         for ur in self.updateRegions:
  869.             (anchorId, anchorType, templateFuncs, name) = ur
  870.             upFunc = u'up_%s_%s' % (count, varname)
  871.             fileobj.write(u'%sdef %s(viewName, view, tid):%s' % (prefix, upFunc, ending))
  872.             fileobj.write(u'%s    out = StringIO()%s' % (prefix, ending))
  873.             for count2 in range(len(templateFuncs)):
  874.                 (func, args) = templateFuncs[count2]
  875.                 fileobj.write(func(u'out', u'', prefix + u'    ', args))
  876.             
  877.             fileobj.write(u'%s    out.seek(0)%s' % (prefix, ending))
  878.             fileobj.write(u'%s    return out%s' % (prefix, ending))
  879.             fileobj.write(u'%s%s.addUpdate(%s,%s,%s,%s, %s)%s' % (prefix, varname, repr(anchorId), repr(anchorType), name, upFunc, repr(name), ending))
  880.             count += 1
  881.         
  882.         for ur in self.configUpdateRegions:
  883.             (anchorId, anchorType, templateFuncs) = ur
  884.             upFunc = u'config_up_%s_%s' % (count, varname)
  885.             fileobj.write(u'%sdef %s(tid):%s' % (prefix, upFunc, ending))
  886.             fileobj.write(u'%s    out = StringIO()%s' % (prefix, ending))
  887.             for count2 in range(len(templateFuncs)):
  888.                 (func, args) = templateFuncs[count2]
  889.                 fileobj.write(func('out', '', prefix + '    ', args))
  890.             
  891.             fileobj.write(u'%s    out.seek(0)%s' % (prefix, ending))
  892.             fileobj.write(u'%s    return out%s' % (prefix, ending))
  893.             fileobj.write(u'%s%s.addConfigUpdate(%s,%s,%s)%s' % (prefix, varname, repr(anchorId), repr(anchorType), upFunc, ending))
  894.             count += 1
  895.         
  896.         for tv in self.trackedViews:
  897.             (anchorId, anchorType, templateFuncs, name) = tv
  898.             repFunc = u'rep_%s_%s' % (count, varname)
  899.             fileobj.write(u'%sdef %s(this, viewName, view, tid):%s' % (prefix, repFunc, ending))
  900.             fileobj.write(u'%s    out = StringIO()%s' % (prefix, ending))
  901.             for count2 in range(len(templateFuncs)):
  902.                 (func, args) = templateFuncs[count2]
  903.                 fileobj.write(func('out', '', prefix + '    ', args))
  904.             
  905.             fileobj.write(u'%s    out.seek(0)%s' % (prefix, ending))
  906.             fileobj.write(u'%s    return out%s' % (prefix, ending))
  907.             fileobj.write(u'%s%s.addView(%s,%s,%s,%s, %s)%s' % (prefix, varname, repr(anchorId), repr(anchorType), name, repFunc, repr(name), ending))
  908.             count += 1
  909.         
  910.         for action in self.triggerActionURLsOnLoad:
  911.             fileobj.write(u'%s%s.addTriggerActionURLOnLoad(fillAttr(%s,locals()))%s' % (prefix, varname, repr(action), ending))
  912.         
  913.         for action in self.triggerActionURLsOnUnload:
  914.             fileobj.write(u'%s%s.addTriggerActionURLOnUnload(fillAttr(%s,locals()))%s' % (prefix, varname, repr(action), ending))
  915.         
  916.         for subHandle in range(len(self.subHandles)):
  917.             newVarName = u'%s_%d' % (varname, subHandle)
  918.             self.subHandles[subHandle].render(fileobj, newVarName)
  919.             fileobj.write(u'%s%s.addSubHandle(%s)%s' % (prefix, varname, newVarName, ending))
  920.         
  921.  
  922.  
  923.  
  924. def fillIfNotNone(obj):
  925.     if obj is None:
  926.         return repr(None)
  927.     else:
  928.         return u'fillAttr(%s,locals())' % repr(obj)
  929.  
  930.